package org.shoukaiseki.aqoeous.builder;

import com.alibaba.fastjson.JSONObject;
import org.shoukaiseki.aqoeous.model.CustomQO;
import org.shoukaiseki.aqoeous.utils.AqoeousUtils;

import java.util.*;

/**
 * com.hkedou.orighere.plugin.aqoeous.builder.AqoeousBuilder
 * <br>
 *
 * @author 蒋カイセキ    Japan-Tokyo  18-12-18 下午1:32<br>
 * ブログ http://www.shoukaiseki.top/<br>
 * E-メール jiang28555@Gmail.com<br>
 **/
public class AqoeousBuilder {

    CustomQO customQO;

    AqoeousBuilder(){
        this.customQO=new CustomQO();
    }

    public AqoeousBuilder qoName(Class qoClass){
        this.customQO.setQoName(AqoeousUtils.unCapitalize(qoClass.getSimpleName()));
        return this;
    }

    public AqoeousBuilder qoName(String qoName){
        this.customQO.setQoName(qoName);
        return this;
    }

    public AqoeousBuilder relationships(RelationshipBuilder... args){

        List relationships=new ArrayList();
        for (RelationshipBuilder arg : args) {
            relationships.add(arg.build());
        }
        this.customQO.setRelationships(relationships);
        return this;
    }

    public AqoeousBuilder qoJsonFromSO(Object baseSO){
        Object obj = JSONObject.toJSON(baseSO);
        if(!(obj instanceof JSONObject)){
           throw new RuntimeException("baseSO 不能为数组等类型,无法转换为 JSONObject");
        }
        customQO.setQoJson((JSONObject)obj);
        return this;
    }


    public AqoeousBuilder qoJson(Object... args){
        if ((args.length & 1) != 0) { // implicit nullcheck of input
            throw new InternalError("length is odd");
        }
        JSONObject qoJson=new JSONObject();
        for (int i = 0; i < args.length; i += 2) {
            @SuppressWarnings("unchecked")
            String k = Objects.requireNonNull(args[i]).toString();
            Object v = args[i+1];
            qoJson.put(k,v);
        }
        customQO.setQoJson(qoJson);
        return this;
    }

    public AqoeousBuilder qoJson(Map<String, Object> map) {
        for (String s : map.keySet()) {
            if (null != map.get(s)) {
                customQO.getQoJson().put(s, map.get(s));
            }
        }
        return this;
    }

    public AqoeousBuilder qoChilds(AqoeousBuilder... qoChilds){
        if(qoChilds.length>0){
            List<CustomQO> customQOList = new ArrayList<>();
            for (AqoeousBuilder qoChild : qoChilds) {
                customQOList.add(qoChild.build());
            }
            customQO.setQoChilds(customQOList);
        }
        return this;
    }

    /**
     * 仅仅显示包含的字段,如果该字段设置了值, excludeFieldList 将失效
     * @param fieldList
     * @return
     */
    public AqoeousBuilder includeFieldList(String... fieldList){
        if (fieldList==null) {
            customQO.setIncludeFieldList(null);
        }else{
            customQO.setIncludeFieldList(Arrays.asList(fieldList));
        }
        return this;
    }


    /**
     *
     * 返回值 排除一些字段
     * 先进行包含设置,再进行排除
     * @param fieldList
     * @return
     */
    public AqoeousBuilder excludeFieldList(String... fieldList){
        if (fieldList==null) {
            customQO.setExcludeFieldList(null);
        }else{
            customQO.setExcludeFieldList(Arrays.asList(fieldList));
        }
        return this;
    }

    public AqoeousBuilder resultName(String resultName){
        customQO.setResultName(resultName);
        return this;
    }

    public AqoeousBuilder mergeParent(boolean mergeParent){
        customQO.setMergeParent(mergeParent);
        return this;
    }

    public AqoeousBuilder listFirstMergeParent(boolean listFirstMergeParent){
        customQO.setListFirstMergeParent(listFirstMergeParent);
        return this;
    }

    public AqoeousBuilder listMergeParent(boolean listMergeParent){
        customQO.setListMergeParent(listMergeParent);
        return this;
    }

    public AqoeousBuilder pageTotalMergeParent(boolean pageTotalMergeParent){
        customQO.setPageTotalMergeParent(pageTotalMergeParent);
        return this;
    }


    public static AqoeousBuilder aqoeous(){
        return new AqoeousBuilder();
    }

    public CustomQO build(){
        return this.customQO;
    }

}
